package com.reebake.ideal.security.oauth2.client;

import cn.hutool.core.util.URLUtil;
import lombok.RequiredArgsConstructor;
import me.zhyd.oauth.request.AuthRequest;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest.Builder;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.util.StringUtils;

import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RequiredArgsConstructor
public class SmartOauth2AuthorizationRequestCustomizer implements Consumer<Builder> {
	private static final Pattern QUERY_PARAM_PATTERN = Pattern.compile("([^&=]+)(=?)([^&]+)?");
	private final ClientRegistrationRepository clientRegistrationRepository;
	private final JustAuthFactory justAuthFactory;

	@Override
	public void accept(Builder builder) {
		StringBuilder registrationId = new StringBuilder();

        builder.attributes(attributeConsumer -> {
			Object value = attributeConsumer.get(OAuth2ParameterNames.REGISTRATION_ID);
			registrationId.append(value);

			builder.parameters(parameters -> {
				// 删除旧数据
				parameters.remove(OAuth2ParameterNames.CLIENT_ID);
				parameters.remove(OAuth2ParameterNames.CLIENT_SECRET);
				parameters.remove(OAuth2ParameterNames.STATE);
				parameters.remove(OAuth2ParameterNames.REDIRECT_URI);
			});
        });

		OAuth2AuthorizationRequest oAuth2AuthorizationRequest = builder.build();
		String state = oAuth2AuthorizationRequest.getState();
		String redirectUri = oAuth2AuthorizationRequest.getRedirectUri();

		AuthRequest authRequest = justAuthFactory.create(registrationId.toString(), redirectUri);
		String authorizeUrl = authRequest.authorize(state);
		String query = URLUtil.toURI(authorizeUrl).getRawQuery();

		builder.parameters(parameters -> {
			Matcher matcher = QUERY_PARAM_PATTERN.matcher(query);
			while (matcher.find()) {
				String name = matcher.group(1);
				String eq = matcher.group(2);
				String value = matcher.group(3);
				parameters.put(name, (value != null ? value : (StringUtils.hasLength(eq) ? "" : null)));
			}
		});
	}
}
